-
Notifications
You must be signed in to change notification settings - Fork 1k
Add prune options to manifest #1226
Add prune options to manifest #1226
Conversation
Tests should be failing for now and the rules in I'm still thinking about the best way to set prune options per project. Can anyone suggest other alternatives? For me, the first option is cleaner, but then we need to make sure that rules are applied (and report on ineffectual rules). The second option is closer to how metadata are formatted currently. @sdboyer: Should prune options affect locks? are they added to the lock and do they change the hash? or are they oblivious to them? |
Did you consider a list of strings? [[constraint]]
name = "github.com/jmank88/nuts"
version = "0.2.0"
prune = { "non-go", "go-tests", "unused-packages" } Would require a bit more parsing/conversion work, but perhaps is more human friendly. |
Now I'm also wondering about the names themselves.
Would Could |
I thought about that but parsing looked annoying so I went for a table instead. Didn't really try it though. But I agree that a table of booleans ( I'm more concerned about where to define the per-project rules though. Another thing that needs will need clarification is how rules cascade... |
I was imaging that the lists would still translate to booleans underneath, and just default to false when absent. Are you suggesting that literal |
Oh, no. Just that with a list it's implicit that omission translates to a The main question is: Should per-project options inherit the global options or no? But first, let me construct a full example to clarify that question: [prune]
unused-packages = true
[[constraint]]
name = "github.com/project/repository"
# Booleans
[constraint.prune]
non-go = true
# List
prune = { "non-go" } What should the prune options for
I personally think that if prune options are defined for a project it should reset and override whatever was defined globally. If that's the case, both options (lists or booleans) are equal. But if per-project rules inherit the global rules, then booleans are more explicit. I feel I'm overthinking this 😁 , but it was the first thing that came to mind when Sam said that we need per-project options. |
But then what would this mean? Seems like it should override the global, but that would make it distinct from omitting it entirely.
|
If overriding the global with a false is a necessary/useful feature, then this makes sense, and can be a If not, then using a list would remove the option. |
which hash, the inputs-digest? nope, they won't affect that. they will affect the hash we eventually generate as part of yes, we absolutely have to support per-dependency overrides of the global options, so we have no choice but to rely on discrete properties that expect booleans. it is a bit more verbose, which isn't the greatest, but the necessity of expressing it one property per line means makes it more diff-friendly. my inclination is to say that, in order to avoid spurious declarations (such as those that plague us in #302), we should make sure that we initially ship this feature with the following validations:
as for the property names themselves, i think we may still have some work to do in articulating exactly what the different prune modes are. when i wrote #944 (comment), i remember thinking that some of these flags may not be entirely orthogonal - that some flags may encompass others. maybe that's not the case, but i need a clear model in my head to be confident about this 😄 it may take a bit of spec-style writing to get there. |
@sdboyer I wrote something to personally understand what each option does. I'll try to formalize it early next week. I'm cleaning this up for now and I had another question. This made me think it might be better to do something like the following: [prune]
non-go = true
[[project]]
name = "github.com/project/test"
non-go = false |
After sleeping on it, I can see many issues coming from the structure I proposed, especially when people try to set prune options on sub-packages... 😞 |
oh? I thought that actually might be really good. what shortcomings do you see? prune options will still be per project, not per package, so that, at least, shouldn't be a problem. |
fac4a7b
to
4471656
Compare
The biggest issue I'm facing right now is the following (only tests are remaining): Assuming we have the following manifest: [[constraint]]
name = "github.com/golang/dep/internal/gps"
version = "0.12.0"
[prune]
non-go = true
[[prune.project]]
name = "github.com/golang/dep"
non-go = false
All my attempts to create a representation that outputs the required TOML failed. And Looking forward to any pointers. |
@pelletier any guidance to offer here? 🙏 |
👋 I'm not sure I fully understand. Given the manifest in #1226 (comment), you want to unmarshal it?
That sounds like a bug in the handling of `omitempty. Do you have some code I could use to reproduce + expected behavior?
It does as of pelletier/go-toml@4e9e0ee (3 days ago)! You can add options to the |
@pelletier My bad. We need to be able to implement a Here is the issue to clarify: To give a concrete example: type rawRootPruneOptions struct {
NonGoFiles bool `toml:"non-go,omitempty"`
Projects []rawPruneProjectOptions `toml:"project,omitempty"`
}
type rawPruneProjectOptions struct {
NonGoFiles bool `toml:"non-go,omitempty"`
}
a := rawRootPruneOptions{
NonGoFiles: false,
Projects: []rawPruneProjectOptions{
rawPruneProjectOptions{
NonGoFiles: false,
},
},
}
b := rawRootPruneOptions{
NonGoFiles: true,
Projects: []rawPruneProjectOptions{
rawPruneProjectOptions{
NonGoFiles: false,
},
},
}
[prune]
non-go = true
[[prune.project]]
name = "github.com/golang/dep"
non-go = false |
16dc0cd
to
505c236
Compare
3d69984
to
f2e422e
Compare
@sdboyer @carolynvs This PR is ready for review and merge. As we discussed, we'll ignore marshaling prune options for the time being since it's not needed. Below is a brief explanation of the current options and what they do:
Some questions: |
f2e422e
to
7f7cd4d
Compare
manifest.go
Outdated
} | ||
case "name": | ||
if root { | ||
warns = append(warns, errors.Errorf("%q should not include a name", "prune")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's create an error constant for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed we only created var
for errors. But I guess we can do that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops! my mistake. Yes, error variable. 😅
manifest_test.go
Outdated
name = "github.com/golang/dep" | ||
`, | ||
wantWarn: []error{ | ||
fmt.Errorf("%q should not include a name", "prune"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's replace this with an error constant.
// | ||
// It will return the root prune options if the project does not have specific | ||
// options or if it does not exists in the manifest. | ||
func (m *Manifest) PruneOptionsFor(pr gps.ProjectRoot) gps.PruneOptions { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this function? I don't see it being used anywhere. Maybe for future usage?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. The other PR will use this function.
} | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestPruneOptionsFor(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can remove this too if PruneOptionsFor()
isn't required.
|
||
func containsErr(s []error, e error) bool { | ||
for _, a := range s { | ||
if a.Error() == e.Error() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can compare the error values directly and not the error message?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't that compare pointers? Unless they refer to same pointer value they won't match.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we create variables for all the possible errors (which I think we almost do), the comparison would happen of the same pointer values. But, if we have some dynamic error, then this is fine. 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We still have some dynamic errors sadly.
@ibrasho did you land on a choice as to whether we stick with just .go (and .asm), or if we should do all the filetypes? |
I think we should add the whole switch statement to be on the safe side. The implementation is part of the other PR (#1219) though. Should we change the configuration key ( |
Signed-off-by: Ibrahim AshShohail <ibra.sho@gmail.com>
Signed-off-by: Ibrahim AshShohail <ibra.sho@gmail.com>
Signed-off-by: Ibrahim AshShohail <ibra.sho@gmail.com>
7f7cd4d
to
fc2d241
Compare
Signed-off-by: Ibrahim AshShohail <ibra.sho@gmail.com>
Signed-off-by: Ibrahim AshShohail <ibra.sho@gmail.com>
cc93dba
to
b439b8d
Compare
To keep a trail of our discussion on Slack (this affect #1219):
I'll add all the extensions found in the import logic in go build.
We haven't discussed this point, @sdboyer. Any input?
Go requires lower-case |
@ibrasho oh yeah, we forgot to talk about package names. fortunately, that one's simple: we don't care if they differ, because we almost never care about package name. almost everything else in dep is based on import path positioning, not package name, and this should follow that pattern. re: case sensitivity, first look and see if the language spec is explicit on the topic. if not, follow the standard compiler/ |
I've checked the spec before and it doesn't mention the extension at all. However, the stdlib implementation is always assuming
About package name/directory name: |
For the options naming (we discussed that the options are a mix of positive and negative rules). I was thinking of it in the following manner: [prune]
non-go= true # Prune non-Go build files globally [prune]
[project]
name = "github.com/awesome/project"
go-tests = true # Prune Go test files in this project [prune]
unused-packages = true # Prune unused packages globally
[project]
name = "github.com/awesome/project"
unused-packages = false # Don't prune unused packages in this project The issue I have now is with
|
i think we're good with |
weeee! |
What does this do / why do we need it?
Add prune options to
dep.Manifest
.WIP:
false
to root prune optionsWhat should your reviewer look out for in this PR?
Generic review.
Do you need help or clarification on anything?
How should prune options be defined for projects?
Here is a list of suggestions:
prune
table under constraints (what about overrides?)or
Which issue(s) does this PR fix?
One more step towards #944